package edu.hawaii.webspider;

import java.util.LinkedList;
import java.util.List;

import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebLink;

/**
 * A demonstration class illustrating how to retrieve and process web pages
 * using HttpUnit.
 * 
 * @author Philip Johnson
 */
public class WebSpiderExample {

  /** Contains the starting url for the crawl. */
  private final String startUrl;
  private static int linkCount = 0;

  static List<String> logging = new LinkedList<String>();

  /**
   * A WebSpider crawls the web and returns info.
   * 
   * @param startUrl
   *          The home url for the crawl.
   */
  public WebSpiderExample(String startUrl) {
    this.startUrl = startUrl;
  }

  /**
   * Returns the number of links found at the startUrl.
   * 
   * @return The number of links.
   * @throws Exception
   *           if problems occur retrieving the startUrl.
   */
  public int getNumLinks() throws Exception {
    // create the conversation object which will maintain state for us
    WebConversation wc = new WebConversation();
    WebRequest request = new GetMethodWebRequest(this.startUrl);
    WebResponse response = wc.getResponse(request);
    return response.getLinks().length;
  }

  /**
   * Retrieves the httpunit home page and counts the number of links on it.
   * 
   * @param args
   *          Ignored.
   * @throws Exception
   *           If problems occur.
   */
  public static void main(String[] args) throws Exception {
    checkArguments(args);

  }

  /**
   * Gets total number of links a given set of webpages contains.
   * 
   * @param url
   *          String representation of the URLs.
   * @param numofpages
   *          number of pages to traverse.
   * @throws Exception
   *           throws exception if webpages are not in valid format or index out
   *           of bound.
   */
  public static void getTotalLinks(String url, int numofpages) throws Exception {

    String tempUrl = url;
    LinkedList<String> crawler = new LinkedList<String>();
    LinkedList<String> visited = new LinkedList<String>();

    int x = 0;

    try {
      WebConversation wc = new WebConversation();
      for (int i = 0; i <= numofpages; i++) {
        x = 0;

        WebResponse response = wc.getResponse(tempUrl);
        visited.add(tempUrl);

        WebLink[] links = response.getLinks();
        while (x < links.length) {
          if (!visited.contains(links[x].toString())) {
            // count += response.getLinks().length;
            crawler.add(links[x].getRequest().getURL().toString());
            logging.add("URL: " + crawler.getLast());
            x++;
            linkCount++;
          }
        }
        tempUrl = crawler.removeFirst();
      }
    } 
    catch (Exception e) {
      e.getMessage();      
      // just to get ride of all those javascript exceptions from webpages.
    }
  }

  /**
   * Shows the most popular links from all the traversed webpages.
   * 
   * @param url
   *          String representation of the URLs.
   * @throws Exception
   *           no exception set yet.
   */
  public static void getMostPopular(String url) throws Exception {
    // no more anything yet, place holder.
  }

  /**
   * 
   * checks what arguments from the command line then invoke corresponding
   * methods.
   * 
   * @param arguments
   *        arguments from command line
   * @throws Exception
   *        index out of bound exceptions
   */
  public static void checkArguments(String[] arguments) throws Exception {
    int numOfPages = 0;

    try {
      String s = arguments[2];
      numOfPages = Integer.parseInt(s);
    } 
    catch (Exception e) {
      System.out.println("Argument format is invalid!");
    }
    if (arguments[0].equals("-totallinks")) {
      getTotalLinks(arguments[1], numOfPages);
    }
    if (arguments[0].equals("-mostpopular")) {
      getMostPopular(arguments[1]);
    }
    if (arguments[3].equals("-logging")) {
      System.out.println("Logging Enabled.");
    }
  }

}
